import axios from "axios"

/**
 * 通过文件资源管理器选择本地文件
 * @param [acceptType] 接受的文件类型，例：‘image/*’
 * @param multiple 是否可选多个文件
 * @return {Promise<FileList>}
 */
export function chooseFile(acceptType: string = '', multiple: boolean = false): Promise<FileList> {
    return new Promise((resolve) => {
        let input: HTMLInputElement = document.querySelector("#lcf-choose-file-input")
        if(!input) {
            input = document.createElement("input")
            input.type = 'file'
            input.id = 'lcf-choose-file-input'
            input.style.display = 'none'
            if(acceptType) input.accept = acceptType
            if(multiple) input.multiple = true
            input.onchange = function () {
                resolve(input.files)
                input.remove()
            }
            document.body.append(input) // 兼容ios,ios下input必须挂载到页面上才可以使用拍照功能
        }
        input.click()
    })
}

/**
 * 选择本地json文件后直接返回json对象/数组
 */
export async function chooseJsonObj() {
    let files = await chooseFile()
    let jsonStr = await file2Json(files[0])
    return JSON.parse(jsonStr)
}

/**
 * 通过请求从服务器读取文件（亦可读取项目内文件）
 * @param url 文件路径
 * @param [fileName] 文件名，默认取url参数末位单元,'/'为分隔符
 * @return {Promise<File>}
 */
export function requestFile(url: string, fileName: string): Promise<File> {
    if(!fileName) {
        const urlList = url.split('/')
        fileName = urlList[urlList.length - 1]
    }
    return new Promise((resolve, reject) => {
        axios({
            method:'get',
            url,
            responseType: 'arraybuffer'
        }).then(res => {
            resolve(new File([res.data], fileName))
        }).catch(error => {
            reject(error.toString())
        })
    })
}

/**
 * 从服务器读取json（亦可读取项目内文件）
 * @param url 文件路径
 * @return {Promise<File>}
 */
export function requestJSON(url: string): Promise<object|[]> {
    return new Promise((resolve, reject) => {
        axios({
            method:'get',
            url,
            responseType: 'json'
        }).then(res => {
            resolve(res.data)
        }).catch(error => {
            reject(error.toString())
        })
    })
}

/**
 * 下载blob格式文件
 */
export function downloadBlob(blob: Blob, name: string) {
    // 创建下载链接
    const save_link = document.createElement("a");

    // 使用标准的 URL.createObjectURL 方法
    save_link.href = URL.createObjectURL(blob);
    save_link.download = name;

    // 添加到文档中（某些浏览器需要此步骤）
    save_link.style.display = 'none';
    document.body.appendChild(save_link);

    // 触发下载
    save_link.click();

    // 清理资源
    setTimeout(() => {
        document.body.removeChild(save_link);
        URL.revokeObjectURL(save_link.href);
    }, 100);
}

/**
 * 下载文本
 * @param text - 要下载的文本内容
 * @param name - 下载的文件名（包括扩展名）
 */
export function downloadText(text: string, name: string) {
    // 创建文本内容的 Blob 对象
    const blob = new Blob([text], { type: 'text/plain' });

    // 创建下载链接
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = name;
    link.style.position = 'fixed';
    link.style.top = '-1000px';  // 移出可视区域

    // 添加到文档
    document.body.appendChild(link);

    // 触发下载
    link.click();

    // 清理资源
    const cleanup = () => {
        if (link.parentNode) {
            link.parentNode.removeChild(link);
        }
        URL.revokeObjectURL(link.href);
    };

    // 延迟清理确保下载开始
    setTimeout(cleanup, 100);
}

/**
 * 下载remote地址文件，使用html标签直接下载在微前端等情况下可能无法约束下载格式。所以应使用此种方式。
 */
export async function downloadByUrl(url: string, name: string) {
    const f = await requestFile(url, name)
    downloadBlob(f, name)
}

/**
 * file转json字符
 */
export async function file2Json(file): Promise<string> {
    return new Promise(resolve => {
        const FR = new FileReader()
        FR.readAsText(file)
        FR.onload = function (e) {
            resolve(e.target.result as string)
        }
    })
}

/**
 * json字符转blob对象
 */
export function json2Blob(jsonObject) {
    return new Blob([jsonObject])
}

/**
 * base64转换
 */
export function toBase64(str){
    let encode = encodeURI(str);
    return btoa(encode);
}

export default {
    chooseFile, requestFile, requestJSON, downloadBlob, file2Json, json2Blob, toBase64, downloadByUrl
}
